'''
File: slimey_v2.py
Author: Niklas Semmler
Description: The second approximation of the slime mold.
             It's description is transferred from XML to Py
'''
#!/usr/bin/python
def configureSimulation(sim):
    ''' simulation definition according to standard plugins '''
    import CompuCellSetup
    from XMLUtils import ElementCC3D

    cc3d        =   ElementCC3D("CompuCell3D")
    potts       =   cc3d.ElementCC3D("Potts")
    potts.ElementCC3D("Dimensions",{"x":160,"y":160,"z":1})
    potts.ElementCC3D("Steps",{},10000)
    potts.ElementCC3D("Temperature",{},15)
    potts.ElementCC3D("NeighborOrder",{},2) # this could make a diff
   
    cellType    =   cc3d.ElementCC3D("Plugin",{"Name":"CellType"})
    cellType.ElementCC3D("CellType", {"TypeName":"Medium",      "TypeId":"0"})
    cellType.ElementCC3D("CellType", {"TypeName":"FoodSource",  "TypeId":"1", "Freeze":""})
    cellType.ElementCC3D("CellType", {"TypeName":"SlimeMold",   "TypeId":"2"})
    cellType.ElementCC3D("CellType", {"TypeName":"Wall",        "TypeId":"3", "Freeze":""})

    contact     =   cc3d.ElementCC3D("Plugin",{"Name":"Contact"})
    contact.ElementCC3D("Energy", {"Type1":"Medium",     "Type2":"Medium"},      0)
    contact.ElementCC3D("Energy", {"Type1":"FoodSource", "Type2":"FoodSource"},  0)
    contact.ElementCC3D("Energy", {"Type1":"FoodSource", "Type2":"Medium"},      0)
    contact.ElementCC3D("Energy", {"Type1":"SlimeMold",  "Type2":"SlimeMold"},  15)
    contact.ElementCC3D("Energy", {"Type1":"SlimeMold",  "Type2":"Medium"},      8)
    contact.ElementCC3D("Energy", {"Type1":"SlimeMold",  "Type2":"FoodSource"},  1)
    contact.ElementCC3D("Energy", {"Type1":"Wall",       "Type2":"Wall"},        0)
    contact.ElementCC3D("Energy", {"Type1":"Wall",       "Type2":"Medium"},      0)
    contact.ElementCC3D("Energy", {"Type1":"Wall",       "Type2":"FoodSource"}, 50)
    contact.ElementCC3D("Energy", {"Type1":"Wall",       "Type2":"SlimeMold"},  50)
   
    player      =   cc3d.ElementCC3D("Plugin", {"Name":"PlayerSettings"})
    player.ElementCC3D("Cell", {"Type":"1", "Color":"red"})
    player.ElementCC3D("Cell", {"Type":"2", "Color":"green"})

    volume      =   cc3d.ElementCC3D("Plugin",{"Name":"Volume"})
    volume.ElementCC3D("TargetVolume",{},1000)
    volume.ElementCC3D("LambdaVolume",{},3.0)

    #chemotaxis  =   cc3d.ElementCC3D("Plugin",{"Name":"Chemotaxis"})
    #attrchtax   =   chemotaxis.ElementCC3D("ChemicalField", {"Source":"FlexibleDiffusionSolverFE", "Name":"ATTR"})
    #attrchtax.ElementCC3D("ChemotaxisByType", {"Type":"SlimeMold" ,"Lambda":250, "SaturationLinearCoef":0.001})
    #reptax      =   chemotaxis.ElementCC3D("ChemicalField", {"Source":"FlexibleDiffusionSolverFE", "Name":"REP"})
    #reptax.ElementCC3D("ChemotaxisByType", {"Type":"SlimeMold" ,"Lambda":-75, "SaturationLinearCoef":0.025})
    
    secretion   = cc3d.ElementCC3D("Plugin", {"Name":"Secretion"})
    attrsecrete = secretion.ElementCC3D("Field", {"Name":"ATTR"})
    attrsecrete.ElementCC3D("Secretion", {"Type":"FoodSource"},30)
    attrsecrete.ElementCC3D("Secretion", {"Type":"SlimeMold"}, 3)
    attrsecrete.ElementCC3D("SecretionOnContact", {"Type":"SlimeMold", "SecreteOnContactWith":"FoodSource"}, 15)
    #repsecrete  = secretion.ElementCC3D("Field", {"Name":"REP"})
    #repsecrete.ElementCC3D("Secretion", {"Type":"Wall"},30)

    flexDiffSolver=cc3d.ElementCC3D("Steppable",{"Type":"FlexibleDiffusionSolverFE"})
    diffusionField=flexDiffSolver.ElementCC3D("DiffusionField")
    diffusionData=diffusionField.ElementCC3D("DiffusionData")
    diffusionData.ElementCC3D("FieldName",{},"ATTR")
    diffusionData.ElementCC3D("DiffusionConstant",{},0.2)
    diffusionData.ElementCC3D("DecayConstant",{},0.3)
    diffusionData.ElementCC3D("DoNotDiffuseTo",{},"Wall")

    diffusionField2=flexDiffSolver.ElementCC3D("DiffusionField")
    diffusionData2=diffusionField.ElementCC3D("DiffusionData")
    diffusionData2.ElementCC3D("FieldName",{},"REP")
    diffusionData2.ElementCC3D("DiffusionConstant",{},0.15)
    diffusionData2.ElementCC3D("DecayConstant",{},0.01)
    diffusionData2.ElementCC3D("DoNotDiffuseTo",{},"FoodSource")

    conn = cc3d.ElementCC3D("Plugin", {"Name":"Connectivity"})
    conn.ElementCC3D("Penalty",{"Type":"SlimeMold"}, 50000)
    
    pifInitializer=cc3d.ElementCC3D("Steppable",{"Type":"PIFInitializer"})
    pifInitializer.ElementCC3D("PIFName",{},"code/maps/fourFS.pif")

    CompuCellSetup.setSimulationXMLDescription(cc3d)

""" 
    secretionData=diffusionField.ElementCC3D("SecretionData")
    secretionData.ElementCC3D("Secretion", {"Type":"FoodSource"},100)
    #secretionData.ElementCC3D("Secretion", {"Type":"SlimeMold"},3)
    secretionData.ElementCC3D("SecretionOnContact", {"Type":"SlimeMold", "SecreteOnContactWith":"FoodSource"},50)
    repfield=chemotaxis.ElementCC3D("ChemicalField", {"Source":"FlexibleDiffusionSolverFE", "Name":"REP"})
    repfield.ElementCC3D("ChemotaxisByType", {"Type":"SlimeMold" ,"Lambda":-75, "SaturationLinearCoef":0.025})

    diffusionField2=flexDiffSolver.ElementCC3D("DiffusionField")
    diffusionData2=diffusionField.ElementCC3D("DiffusionData")
    diffusionData2.ElementCC3D("FieldName",{},"REP")
    diffusionData2.ElementCC3D("DiffusionConstant",{},0.20)
    diffusionData2.ElementCC3D("DecayConstant",{},0.01)
    diffusionData2.ElementCC3D("DoNotDiffuseTo",{},"FoodSource")
    secretionData2=diffusionField.ElementCC3D("SecretionData")
    secretionData2.ElementCC3D("Secretion", {"Type":"Wall"},100)
"""

# basics of every CC3D script
import sys
from os import environ
import string
sys.path.append(environ["PYTHON_MODULE_PATH"])
import CompuCellSetup

sim,simthread = CompuCellSetup.getCoreSimulationObjects()

configureSimulation(sim)

CompuCellSetup.initializeSimulationObjects(sim,simthread)

steppableRegistry = CompuCellSetup.getSteppableRegistry()

from custom_steppables import SecretionSteppable
secrete = SecretionSteppable(sim)
steppableRegistry.registerSteppable(secrete)

CompuCellSetup.mainLoop(sim,simthread,steppableRegistry)


# custom steppables
#secrete = SecretionSteppable(sim)
#steppableRegistry.registerSteppable(secrete)

#def main(argv=sys.argv):
#return 0

#if __name__ == '__main__':
#    sys.exit(main())

